/**
 * 响应码枚举
 * 对应后端 ResultCode 枚举
 *
 * @author yunjian.ban
 * @since 2024/10/29
 */
export enum RESULT_CODE {
  // 成功
  SUCCESS = '00000',

  // 用户端错误
  USER_ERROR = 'A0001',
  REPEAT_SUBMIT_ERROR = 'A0002',

  // 用户登录异常
  USER_LOGIN_ERROR = 'A0200',
  USER_NOT_EXIST = 'A0201',
  USER_ACCOUNT_LOCKED = 'A0202',
  USER_ACCOUNT_INVALID = 'A0203',

  // 用户名密码错误
  USERNAME_OR_PASSWORD_ERROR = 'A0210',
  PASSWORD_ENTER_EXCEED_LIMIT = 'A0211',
  CLIENT_AUTHENTICATION_FAILED = 'A0212',

  // 验证码错误
  VERIFY_CODE_TIMEOUT = 'A0213',
  VERIFY_CODE_ERROR = 'A0214',

  // Token相关错误
  TOKEN_INVALID = 'A0230',
  REFRESH_TOKEN_INVALID = 'A0232',
  TOKEN_ACCESS_FORBIDDEN = 'A0231',

  // 权限相关错误
  AUTHORIZED_ERROR = 'A0300',
  ACCESS_UNAUTHORIZED = 'A0301',
  FORBIDDEN_OPERATION = 'A0302',

  // 参数错误
  PARAM_ERROR = 'A0400',
  RESOURCE_NOT_FOUND = 'A0401',
  PARAM_IS_NULL = 'A0410',

  // 文件上传错误
  USER_UPLOAD_FILE_ERROR = 'A0700',
  USER_UPLOAD_FILE_TYPE_NOT_MATCH = 'A0701',
  USER_UPLOAD_FILE_SIZE_EXCEEDS = 'A0702',
  USER_UPLOAD_IMAGE_SIZE_EXCEEDS = 'A0703',

  // 系统执行错误
  SYSTEM_EXECUTION_ERROR = 'B0001',
  SYSTEM_EXECUTION_TIMEOUT = 'B0100',
  SYSTEM_ORDER_PROCESSING_TIMEOUT = 'B0101',

  // 系统容灾和限流
  SYSTEM_DISASTER_RECOVERY_TRIGGER = 'B0200',
  FLOW_LIMITING = 'B0210',
  DEGRADATION = 'B0220',

  // 系统资源错误
  SYSTEM_RESOURCE_ERROR = 'B0300',
  SYSTEM_RESOURCE_EXHAUSTION = 'B0310',
  SYSTEM_RESOURCE_ACCESS_ERROR = 'B0320',
  SYSTEM_READ_DISK_FILE_ERROR = 'B0321',

  // 第三方服务错误
  CALL_THIRD_PARTY_SERVICE_ERROR = 'C0001',
  MIDDLEWARE_SERVICE_ERROR = 'C0100',
  INTERFACE_NOT_EXIST = 'C0113',

  // 消息服务错误
  MESSAGE_SERVICE_ERROR = 'C0120',
  MESSAGE_DELIVERY_ERROR = 'C0121',
  MESSAGE_CONSUMPTION_ERROR = 'C0122',
  MESSAGE_SUBSCRIPTION_ERROR = 'C0123',
  MESSAGE_GROUP_NOT_FOUND = 'C0124',

  // 数据库错误
  DATABASE_ERROR = 'C0300',
  DATABASE_TABLE_NOT_EXIST = 'C0311',
  DATABASE_COLUMN_NOT_EXIST = 'C0312',
  DATABASE_DUPLICATE_COLUMN_NAME = 'C0321',
  DATABASE_DEADLOCK = 'C0331',
  DATABASE_PRIMARY_KEY_CONFLICT = 'C0341'
}

/**
 * 响应码描述映射
 */
export const RESULT_CODE_MAP = {
  [RESULT_CODE.SUCCESS]: '一切ok',

  [RESULT_CODE.USER_ERROR]: '用户端错误',
  [RESULT_CODE.REPEAT_SUBMIT_ERROR]: '您的请求已提交，请不要重复提交或等待片刻再尝试。',

  [RESULT_CODE.USER_LOGIN_ERROR]: '用户登录异常',
  [RESULT_CODE.USER_NOT_EXIST]: '用户不存在',
  [RESULT_CODE.USER_ACCOUNT_LOCKED]: '用户账户被冻结',
  [RESULT_CODE.USER_ACCOUNT_INVALID]: '用户账户已作废',

  [RESULT_CODE.USERNAME_OR_PASSWORD_ERROR]: '用户名或密码错误',
  [RESULT_CODE.PASSWORD_ENTER_EXCEED_LIMIT]: '用户输入密码次数超限',
  [RESULT_CODE.CLIENT_AUTHENTICATION_FAILED]: '客户端认证失败',

  [RESULT_CODE.VERIFY_CODE_TIMEOUT]: '验证码已过期',
  [RESULT_CODE.VERIFY_CODE_ERROR]: '验证码错误',

  [RESULT_CODE.TOKEN_INVALID]: 'token无效或已过期',
  [RESULT_CODE.REFRESH_TOKEN_INVALID]: '刷新 token 无效或已过期',
  [RESULT_CODE.TOKEN_ACCESS_FORBIDDEN]: 'token已被禁止访问',

  [RESULT_CODE.AUTHORIZED_ERROR]: '访问权限异常',
  [RESULT_CODE.ACCESS_UNAUTHORIZED]: '访问未授权',
  [RESULT_CODE.FORBIDDEN_OPERATION]: '演示环境禁止新增、修改和删除数据，请本地部署后测试',

  [RESULT_CODE.PARAM_ERROR]: '用户请求参数错误',
  [RESULT_CODE.RESOURCE_NOT_FOUND]: '请求资源不存在',
  [RESULT_CODE.PARAM_IS_NULL]: '请求必填参数为空',

  [RESULT_CODE.USER_UPLOAD_FILE_ERROR]: '用户上传文件异常',
  [RESULT_CODE.USER_UPLOAD_FILE_TYPE_NOT_MATCH]: '用户上传文件类型不匹配',
  [RESULT_CODE.USER_UPLOAD_FILE_SIZE_EXCEEDS]: '用户上传文件太大',
  [RESULT_CODE.USER_UPLOAD_IMAGE_SIZE_EXCEEDS]: '用户上传图片太大',

  [RESULT_CODE.SYSTEM_EXECUTION_ERROR]: '系统执行出错',
  [RESULT_CODE.SYSTEM_EXECUTION_TIMEOUT]: '系统执行超时',
  [RESULT_CODE.SYSTEM_ORDER_PROCESSING_TIMEOUT]: '系统订单处理超时',

  [RESULT_CODE.SYSTEM_DISASTER_RECOVERY_TRIGGER]: '系统容灾功能被出发',
  [RESULT_CODE.FLOW_LIMITING]: '系统限流',
  [RESULT_CODE.DEGRADATION]: '系统功能降级',

  [RESULT_CODE.SYSTEM_RESOURCE_ERROR]: '系统资源异常',
  [RESULT_CODE.SYSTEM_RESOURCE_EXHAUSTION]: '系统资源耗尽',
  [RESULT_CODE.SYSTEM_RESOURCE_ACCESS_ERROR]: '系统资源访问异常',
  [RESULT_CODE.SYSTEM_READ_DISK_FILE_ERROR]: '系统读取磁盘文件失败',

  [RESULT_CODE.CALL_THIRD_PARTY_SERVICE_ERROR]: '调用第三方服务出错',
  [RESULT_CODE.MIDDLEWARE_SERVICE_ERROR]: '中间件服务出错',
  [RESULT_CODE.INTERFACE_NOT_EXIST]: '接口不存在',

  [RESULT_CODE.MESSAGE_SERVICE_ERROR]: '消息服务出错',
  [RESULT_CODE.MESSAGE_DELIVERY_ERROR]: '消息投递出错',
  [RESULT_CODE.MESSAGE_CONSUMPTION_ERROR]: '消息消费出错',
  [RESULT_CODE.MESSAGE_SUBSCRIPTION_ERROR]: '消息订阅出错',
  [RESULT_CODE.MESSAGE_GROUP_NOT_FOUND]: '消息分组未查到',

  [RESULT_CODE.DATABASE_ERROR]: '数据库服务出错',
  [RESULT_CODE.DATABASE_TABLE_NOT_EXIST]: '表不存在',
  [RESULT_CODE.DATABASE_COLUMN_NOT_EXIST]: '列不存在',
  [RESULT_CODE.DATABASE_DUPLICATE_COLUMN_NAME]: '多表关联中存在多个相同名称的列',
  [RESULT_CODE.DATABASE_DEADLOCK]: '数据库死锁',
  [RESULT_CODE.DATABASE_PRIMARY_KEY_CONFLICT]: '主键冲突'
};

/**
 * 响应码分类
 */
export const RESULT_CODE_CATEGORIES = {
  SUCCESS: {
    name: '成功',
    codes: [RESULT_CODE.SUCCESS]
  },
  USER_ERROR: {
    name: '用户端错误',
    codes: [
      RESULT_CODE.USER_ERROR,
      RESULT_CODE.REPEAT_SUBMIT_ERROR,
      RESULT_CODE.USER_LOGIN_ERROR,
      RESULT_CODE.USER_NOT_EXIST,
      RESULT_CODE.USER_ACCOUNT_LOCKED,
      RESULT_CODE.USER_ACCOUNT_INVALID,
      RESULT_CODE.USERNAME_OR_PASSWORD_ERROR,
      RESULT_CODE.PASSWORD_ENTER_EXCEED_LIMIT,
      RESULT_CODE.CLIENT_AUTHENTICATION_FAILED,
      RESULT_CODE.VERIFY_CODE_TIMEOUT,
      RESULT_CODE.VERIFY_CODE_ERROR,
      RESULT_CODE.TOKEN_INVALID,
      RESULT_CODE.REFRESH_TOKEN_INVALID,
      RESULT_CODE.TOKEN_ACCESS_FORBIDDEN,
      RESULT_CODE.AUTHORIZED_ERROR,
      RESULT_CODE.ACCESS_UNAUTHORIZED,
      RESULT_CODE.FORBIDDEN_OPERATION,
      RESULT_CODE.PARAM_ERROR,
      RESULT_CODE.RESOURCE_NOT_FOUND,
      RESULT_CODE.PARAM_IS_NULL,
      RESULT_CODE.USER_UPLOAD_FILE_ERROR,
      RESULT_CODE.USER_UPLOAD_FILE_TYPE_NOT_MATCH,
      RESULT_CODE.USER_UPLOAD_FILE_SIZE_EXCEEDS,
      RESULT_CODE.USER_UPLOAD_IMAGE_SIZE_EXCEEDS
    ]
  },
  SYSTEM_ERROR: {
    name: '系统执行错误',
    codes: [
      RESULT_CODE.SYSTEM_EXECUTION_ERROR,
      RESULT_CODE.SYSTEM_EXECUTION_TIMEOUT,
      RESULT_CODE.SYSTEM_ORDER_PROCESSING_TIMEOUT,
      RESULT_CODE.SYSTEM_DISASTER_RECOVERY_TRIGGER,
      RESULT_CODE.FLOW_LIMITING,
      RESULT_CODE.DEGRADATION,
      RESULT_CODE.SYSTEM_RESOURCE_ERROR,
      RESULT_CODE.SYSTEM_RESOURCE_EXHAUSTION,
      RESULT_CODE.SYSTEM_RESOURCE_ACCESS_ERROR,
      RESULT_CODE.SYSTEM_READ_DISK_FILE_ERROR
    ]
  },
  THIRD_PARTY_ERROR: {
    name: '第三方服务错误',
    codes: [
      RESULT_CODE.CALL_THIRD_PARTY_SERVICE_ERROR,
      RESULT_CODE.MIDDLEWARE_SERVICE_ERROR,
      RESULT_CODE.INTERFACE_NOT_EXIST,
      RESULT_CODE.MESSAGE_SERVICE_ERROR,
      RESULT_CODE.MESSAGE_DELIVERY_ERROR,
      RESULT_CODE.MESSAGE_CONSUMPTION_ERROR,
      RESULT_CODE.MESSAGE_SUBSCRIPTION_ERROR,
      RESULT_CODE.MESSAGE_GROUP_NOT_FOUND,
      RESULT_CODE.DATABASE_ERROR,
      RESULT_CODE.DATABASE_TABLE_NOT_EXIST,
      RESULT_CODE.DATABASE_COLUMN_NOT_EXIST,
      RESULT_CODE.DATABASE_DUPLICATE_COLUMN_NAME,
      RESULT_CODE.DATABASE_DEADLOCK,
      RESULT_CODE.DATABASE_PRIMARY_KEY_CONFLICT
    ]
  }
};

/**
 * 获取响应码描述
 * @param code 响应码
 * @returns 响应码描述
 */
export function getResultCodeMessage(code: string): string {
  return RESULT_CODE_MAP[code as RESULT_CODE] || '未知错误';
}

/**
 * 判断是否为成功响应码
 * @param code 响应码
 * @returns 是否为成功响应码
 */
export function isSuccessCode(code: string): boolean {
  return code === RESULT_CODE.SUCCESS;
}

/**
 * 判断是否为Token过期响应码
 * @param code 响应码
 * @returns 是否为Token过期响应码
 */
export function isTokenInvalidCode(code: string): boolean {
  return code === RESULT_CODE.TOKEN_INVALID;
}

/**
 * 判断是否为用户端错误
 * @param code 响应码
 * @returns 是否为用户端错误
 */
export function isUserError(code: string): boolean {
  return RESULT_CODE_CATEGORIES.USER_ERROR.codes.includes(code as RESULT_CODE);
}

/**
 * 判断是否为系统错误
 * @param code 响应码
 * @returns 是否为系统错误
 */
export function isSystemError(code: string): boolean {
  return RESULT_CODE_CATEGORIES.SYSTEM_ERROR.codes.includes(code as RESULT_CODE);
}

/**
 * 判断是否为第三方服务错误
 * @param code 响应码
 * @returns 是否为第三方服务错误
 */
export function isThirdPartyError(code: string): boolean {
  return RESULT_CODE_CATEGORIES.THIRD_PARTY_ERROR.codes.includes(code as RESULT_CODE);
}

/**
 * 获取错误分类
 * @param code 响应码
 * @returns 错误分类名称
 */
export function getErrorCategory(code: string): string {
  if (isSuccessCode(code)) {
    return RESULT_CODE_CATEGORIES.SUCCESS.name;
  }
  if (isUserError(code)) {
    return RESULT_CODE_CATEGORIES.USER_ERROR.name;
  }
  if (isSystemError(code)) {
    return RESULT_CODE_CATEGORIES.SYSTEM_ERROR.name;
  }
  if (isThirdPartyError(code)) {
    return RESULT_CODE_CATEGORIES.THIRD_PARTY_ERROR.name;
  }
  return '未知错误';
}
